<template>
  <div>
    <el-dialog
      v-model="isShow"
      :title="$demoi18n('panel.thresholdSetting.dialogTitle')"
      width="630px"
      top="8.4vh"
      append-to-body
      destroy-on-close
      :close-on-click-modal="false"
      :class="`${customClass} ${visualThemeClassName} threshold-setting-table-dialog ${xvueNameSpace}`"
    >
      <div class="threshold-setting-main">
        <el-form
          ref="form"
          class="form"
          label-position="right"
          :model="thresholdForm"
          :rules="rules"
          label-width="85px"
        >
          <VsFormItem :label="$demoi18n('word.threshold')" class="el-form-table-switch">
            <el-switch v-model="thresholdForm.isThreshold"></el-switch>
          </VsFormItem>

          <div
            v-if="thresholdForm.isThreshold"
            class="config-table"
          >
            <el-button
              class="btn-sure button-sure"
              size="small"
              icon="CirclePlus"
              @click.stop="addNewRow(thresholdTemp, thresholdItem)"
            >{{ $demoi18n('btn.add') }}</el-button>
            <Helptip>{{ $demoi18n('panel.labelTip.tableThresholdTip') }}</Helptip>
            <el-table
              ref="table"
              class="config-panel-table mapping-table"
              :data="thresholdForm.thresholdData"
              :row-style="{ height: '25px' }"
              :header-row-style="{ height: '25px' }"
              max-height="500"
              :header-cell-style="{ lineHeight: '15px' }"
            >
              <el-table-column
                :label="$demoi18n('panelData.mapping.field')"
                :min-width="170"
              >
                <template #header="{column}">
                  <ThCell :label="column.label" />
                </template>
                <template #default="scope">
                  <VsFormItem>
                    <ValueInputer
                      v-model:value="scope.row.field"
                      :enum-values="fieldList"
                      @change="handleRowTypeChange(scope.row, scope.$index)"
                    />
                  </VsFormItem>
                </template>
              </el-table-column>
              <el-table-column
                :label="$demoi18n('word.valueType')"
              >
                <template #header="{column}">
                  <ThCell :label="column.label" />
                </template>
                <template #default="scope">
                  <template v-if="isSelectType">
                    <el-select v-model="scope.row.fieldType" placeholder="">
                      <el-option v-for="item in valueTypeList" :key="item.value" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                  </template>
                  <template v-else>
                    {{ getCurFieldObj(scope.row.fieldType).label }}
                  </template>
                </template>
              </el-table-column>
              <el-table-column
                :label="$demoi18n('panel.label.thresholdRange')"
                :min-width="170"
              >
                <template #header="{column}">
                  <el-tooltip
                    placement="top"
                    :content="`${column.label} eg: a <= x < b`"
                    :effect="xvueTheme"
                  >
                    <!-- threshold-setting-table表头 -->
                    <div style="display: inline-block; width: 100%; overflow:hidden; text-overflow: ellipsis;">
                      <span>{{ column.label }}</span>
                      <span
                        :style="{
                          fontSize: '12px',
                          marginLeft: '5px',
                          color: xvueTheme === 'dark'? '#fff': '#999',
                        }"
                      >eg: a &lt;= x &lt; b</span>
                    </div>
                  </el-tooltip>
                </template>

                <template #default="scope">
                  <div
                    v-if="getCurFieldObj(scope.row.fieldType).type === 'num'"
                    class="threshold-column"
                  >
                    <VsFormItem
                      :prop="`thresholdData[${scope.$index}].min`"
                      :rules="genRulesByKey('threshold.min')"
                    >
                      <!-- threshold-setting-table num最小值 -->
                      <el-input-number
                        v-model="scope.row.min"
                        :placeholder="$demoi18n('panel.thresholdSetting.leftVal')"
                        size="small"
                        :style="{ width: '100%' }"
                        :controls="false"
                        @blur="checkThreshold"
                      ></el-input-number>
                    </VsFormItem>
                    <span :style="{ margin: '0 3px' }">-</span>
                    <!-- threshold-setting-table num最大值 -->
                    <VsFormItem
                      :prop="`thresholdData[${scope.$index}].max`"
                      :rules="genRulesByKey('threshold.max')"
                    >
                      <el-input-number
                        v-model="scope.row.max"
                        :placeholder="$demoi18n('panel.thresholdSetting.rightVal')"
                        size="small"
                        :style="{ width: '100%' }"
                        :controls="false"
                        @blur="checkThreshold"
                      ></el-input-number>
                    </VsFormItem>
                  </div>
                  <div
                    v-else
                    class="threshold-column"
                  >
                    <VsFormItem
                      class="threshold-column-select"
                      :prop="`thresholdData[${scope.$index}].text`"
                      :rules="genRulesByKey('threshold.text')"
                    >
                      <ValueInputer
                        v-model:value="scope.row.text"
                        :enum-values="scope.row.textList"
                      />
                    </VsFormItem>
                  </div>
                </template>
              </el-table-column>

              <el-table-column
                prop="color"
                :label="$demoi18n('panel.thresholdSetting.fontColor')"
                :min-width="55"
              >
                <template #header="{column}">
                  <ThCell :label="column.label" />
                </template>
                <template #default="scope">
                  <el-color-picker
                    v-model="scope.row.color"
                    :popper-class="'vis-color-picker-panel-' + xvueTheme"
                    color-format="hex"
                    :predefine="predefineColors"
                    size="small"
                    :style="{ 'vertical-align': 'bottom' }"
                    append-to=".threshold-setting-table-dialog"
                  ></el-color-picker>
                </template>
              </el-table-column>
              <el-table-column :label="$demoi18n('panel.thresholdSetting.isEntireRow')" :min-width="80">
                <template #header="{column}">
                  <ThCell :label="column.label" />
                </template>
                <template #default="scope">
                  <el-checkbox v-model="scope.row.isEntireRow"></el-checkbox>
                </template>
              </el-table-column>
              <el-table-column :label="$demoi18n('word.operation')" :min-width="30">
                <template #header="{column}">
                  <ThCell :label="column.label" />
                </template>
                <template #default="scope">
                  <el-button
                    icon="Delete"
                    :link="true"
                    type="primary"
                    @click.stop="deleteCurRow(scope.$index)"
                  ></el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-form>
        <div class="action-button-group">
          <el-button
            class="button-sure"
            size="small"
            type="primary"
            @click="handleSave()"
          >{{
            $demoi18n('btn.confirm')
          }}</el-button>
          <el-button
            class="button-cancel"
            size="small"
            @click="cancel()"
          >{{ $demoi18n('btn.close') }}</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script lang='jsx'>
import Helptip from '@/components/common/helptip/helptip.vue';
import ThCell from '@/components/common/th-cell/th-cell.vue';
import ValueInputer from '@/components/common/value-inputer/value-inputer.vue';
import { fieldTypeOptions } from '@/components/panel-data/components/table-column-default-config';
import { genRulesByKey } from '@/utils/rules';
import { mapState } from 'vuex';

export default {
  name: 'ThresholdSetting',
  components: { ValueInputer, Helptip, ThCell },
  props: ['form', 'config', 'activeColorRadio', 'activeColorSwitch', 'nameList', 'fieldList', 'tableData', 'useFor', 'isSelectType'],
  emits: ['save'],
  data() {
    return {
      xvueNameSpace: process.env.xvueNameSpace, // 给挂载在body下的元素加上主类名
      xvueTheme: window._adoPremise.uc.theme,
      customClass: `threshold-setting-dialog threshold-setting-dialog-${window._adoPremise.uc.theme || 'light'}`,
      isShow: false,
      thresholdForm: {},
      thresholdItem: {
        field: '',
        fieldType: 'number',
        min: 0,
        max: 0,
        text: '',
        textList: [],
        color: '',
        isEntireRow: false,
      },
      thresholdTemp: {},
      dataTypeOptions: fieldTypeOptions,
      stringDataOption: [],
      predefineColors: ['#ff5071'],
      rules: {},
    };
  },
  computed: {
    thisComp() {
      return this;
    },
    valueTypeList() {
      return [
        { value: 'number', label: this.$demoi18n('word.numValue') },
        { value: 'string', label: this.$demoi18n('word.string') }];
    },
    ...mapState({
      componentsData: state => state.VisualComponentsModule.componentsData,
    }),
  },
  watch: {},
  methods: {
    genRulesByKey,
    openDialog() {
      const { isThreshold, threshold } = this.form;
      const thresholdData = JSON.parse(JSON.stringify(threshold));
      thresholdData.forEach(thresholdItem => {
        const curColumn = this.tableData.find(column => column.field === thresholdItem.field);

        // 通过在阈值设置中选择字段类型的,字段类型取设置中的,否则就按照表格组件一样从数据面板取字段类型
        thresholdItem.fieldType = this.isSelectType ? thresholdItem.fieldType : (curColumn && curColumn.fieldType) || 'number';
        if (this.getCurFieldObj(thresholdItem.fieldType).type !== 'num' && thresholdItem.field) {
          this.nameList.map(val => val[thresholdItem.field]);
          const arr = this.nameList.map(n => {
            if (n[thresholdItem.field] !== undefined) {
              return n[thresholdItem.field].toString();
            }
            return null;
          });
          thresholdItem.textList = Array.from(new Set(arr));
        }
      });
      this.thresholdForm = {
        isThreshold,
        thresholdData,
      };
      this.isShow = true;
    },
    cancel() {
      this.isShow = false;
    },

    addNewRow(temp, item) {
      const threTemp = JSON.parse(JSON.stringify(item));
      this.thresholdForm.thresholdData.push(threTemp);
    },
    deleteCurRow(index) {
      this.thresholdForm.thresholdData.splice(index, 1);
      this.checkThreshold();
    },
    getCurFieldObj(fieldType) {
      const obj = this.dataTypeOptions.find(option => option.value === fieldType);
      return obj || {};
    },
    handleRowTypeChange(row) {
      const curColumn = this.tableData.find(column => column.field === row.field);
      row.fieldType = (curColumn && curColumn.fieldType) || 'number';

      if (this.getCurFieldObj(row.fieldType).type !== 'num' && row.field) {
        row.min = 0;
        row.max = 0;
        const arr = this.nameList.map(n => {
          if (n[row.field] !== null) {
            return n[row.field].toString();
          }
          return '';
        });
        row.textList = Array.from(new Set(arr));
      }
      if (this.getCurFieldObj(row.fieldType).type === 'num' && row.field) {
        row.text = '';
      }
    },
    getGroup(fType) {
      const group = [];
      const allGroup = this.thresholdForm.thresholdData.filter(
        curObj => this.getCurFieldObj(curObj.fieldType).type === fType,
      );
      allGroup.forEach(curObj => {
        const numFieldArr = Array.from(new Set(group.map(obj => obj[0].fieldType)));
        const index = numFieldArr.indexOf(curObj.fieldType);
        if (index > -1) {
          group[index].push(curObj);
        } else {
          group.push([curObj]);
        }
      });
      return group;
    },
    checkNumThreshold(numGroup) {
      let errorText = '';

      // 遍历各数据类型各自校验
      for (let m = 0; m < numGroup.length; m++) {
        const numFieldSet = new Set(numGroup[m].map(num => num.field));
        const numFieldArr = Array.from(numFieldSet);

        // 遍历各字段各自校验
        for (let k = 0; k < numFieldArr.length; k++) {
          const curFieldArr = numGroup[m].filter(num => num.field === numFieldArr[k]);
          const rangeArray = [];
          curFieldArr.forEach((item, index) => {
            rangeArray[index] = [item.min, item.max];
          });

          // 校验错误区间
          for (let i = 0; i < rangeArray.length; i++) {
            if (rangeArray[i][0] >= rangeArray[i][1]) {
              errorText = this.$demoi18n('message.wrongThresholdRange');
              this.emitToPanel(errorText);
              return false;
            }
          }

          // 校验重复区间
          if (!this.checkNumThresholdRepetition(rangeArray)) {
            return false;
          }
        }
      }
      return true;
    },
    checkNumThresholdRepetition(rangeArray) {
      let errorText = '';
      for (let i = 0; i < rangeArray.length; i++) {
        for (let j = 0; j < i; j++) {
          if (
            (rangeArray[i][0] >= rangeArray[j][0] && rangeArray[i][0] < rangeArray[j][1]) ||
                (rangeArray[i][1] > rangeArray[j][0] && rangeArray[i][1] < rangeArray[j][1])
          ) {
            errorText = this.$demoi18n('message.thresholdRepetition');
            this.emitToPanel(errorText);
            return false;
          }
        }
      }
      return true;
    },
    checkStrThreshold(strGroup) {
      let errorText = '';

      // 遍历各数据类型各自校验
      for (let m = 0; m < strGroup; m++) {
        const stringFieldSet = new Set(strGroup[m].map(string => string.field));
        const stringFieldArr = Array.from(stringFieldSet);

        // 遍历各字段各自校验
        for (let i = 0; i < stringFieldArr.length; i++) {
          const curFieldArr = strGroup[m].filter(num => num.field === stringFieldArr[i]);
          const textArray = curFieldArr.map(data => data.text).filter(text => text !== '');
          const textSet = new Set(textArray);
          textSet.delete('');

          // 校验重复值
          if (textSet.size < textArray.length) {
            errorText = this.$demoi18n('message.duplicateStringThreshold');
            this.emitToPanel(errorText);
            return false;
          }
        }
      }

      return true;
    },
    checkThreshold() {
      const stringGroup = this.getGroup('str');
      const numberGroup = this.getGroup('num');
      let valid = false;
      if (stringGroup.length > 0) {
        valid = this.checkStrThreshold(stringGroup);
      }
      if (numberGroup.length > 0) {
        valid = this.checkNumThreshold(numberGroup);
      }

      return valid;
    },
    emitToPanel(error) {
      this.$message.error(error);
    },

    handleSave() {
      if (!this.thresholdForm.isThreshold || this.thresholdForm.thresholdData.length === 0) {
        this.$emit('save', this.thresholdForm);
        this.cancel();
        return;
      }
      this.$refs.form.validate(valid => {
        if (!valid) {
          return;
        }
        if (!this.checkThreshold()) {
          return;
        }
        this.$emit('save', this.thresholdForm);
        this.cancel();
      });
    },
  },
};
</script>

<style lang="less">
@import '../../../common/color-picker-panel.less';
</style>
<style lang="less" scoped>
// .threshold-setting-dialog {
  .threshold-setting-main {
    .form {
      width: 100%;
      :deep(.el-form-item) {
        margin-bottom: 0;
        .el-form-item__label {
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }
      }
      .el-form-table-switch {
        align-items: center;
      }
      .config-table {
        :deep(.el-table) {
          .el-form-item__error {
            top: 100%;
            padding-top: 0;
            white-space: normal;
            word-break: break-word;
          }
          .is-error {
            margin-bottom: 15px;
          }
          .cell {
            padding: 0 3px !important;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            .threshold-column {
              display: flex;
              align-items: center;
              .threshold-column-select {
                display: contents;
              }
            }
            .el-input__inner {
              padding: 0 5px !important;
            }
          }
          td,
          th {
            padding: 5px 0 !important;
          }
          th div {
            display: inline;
            line-height: 15px;
          }
          .el-table__row > td {
            border: none;
          }
        }
        :deep(.el-form-item__content) {
          margin-left: 0 !important;
        }
      }
    }
  }

  .action-button-group {
    text-align: right;
    padding-top: 20px;
    .button-sure {
      padding: 9px 35px;
      border-radius: 0;
    }
    .button-cancel {
      padding: 9px 35px;
      border-radius: 0;
    }
  }
// }
.icon-library-dialog-dark {
  .icon-library-main {
    background-color: #071f30;
  }
  .action-button-group {
    .button-sure {
      background-color: #0eb4c2;
      color: #fff;
    }
    .button-cancel {
      background-color: #064559;
      border-color: #064559;

      color: #fff;
    }
  }
}
</style>

<style lang="less">
@font_color_dark: #98cae6;
@borderColor_dark: #116584;
@textColor_dark: #ffffff;
@bgColor_dark: #000c17;
@font_color_active_dark: #00f0ff;
@background_color_dark: #071f30;
.threshold-setting-dialog-dark {
  .el-dialog__header {
    background: #183c5a;
    .el-dialog__title {
      color: #fff;
    }

    .el-dialog__headerbtn {
      .el-dialog__close {
        color: #fff;
      }
    }
  }

  .el-dialog__body {
    background: #0e2b40;

    .el-form-item__label {
      color: @font_color_dark;
    }

    .el-input {
      .el-input__inner {
        border-color: @borderColor_dark;
        color: @textColor_dark;
        background-color: @bgColor_dark;
      }

      .el-input__icon {
        color: @borderColor_dark;
      }
    }

    .el-radio-group {
      .el-radio {
        color: @textColor_dark;

        .el-radio__input {
          .el-radio__inner {
            border-color: @font_color_active_dark;
            background-color: unset;
          }
        }

        .is-checked {
          .el-radio__inner {
            &::after {
              background-color: @font_color_active_dark;
            }
          }
        }

        .el-radio__label {
          color: #fff;
        }
      }
      .is-checked {
        .el-radio__label {
          color: #00f0ff;
        }
      }
    }

    .el-switch__core {
      background-color: #064559;
      border-color: #064559;
    }

    .el-switch.is-checked {
      .el-switch__core {
        background-color: #0eb4c2;
        border-color: #0eb4c2;
      }
    }

    .el-color-picker {
      .el-color-picker__trigger {
        border-color: @borderColor_dark;
      }
    }

    // 表格
    .config-panel-table {
      color: @font_color_dark;
      background-color: @background_color_dark;

      &::before {
        background-color: @background_color_dark;
      }

      .cell {
        padding: 0 3px !important;
      }
      td,
      th {
        padding: 5px 0 !important;
      }

      .el-table__header {
        th {
          background-color: #122b40 !important;
          border-color: #122b40;
          color: @font_color_dark;
        }
      }

      .el-table__body {
        tr {
          td {
            background-color: @background_color_dark;
            border-color: @background_color_dark;

            .icon-library-open {
              background-color: unset;
              border-color: #0eb4c2;
            }
          }
        }
      }

      .el-table__empty-block {
        background-color: #093758;

        .el-table__empty-text {
          color: @font_color_active_dark;
        }
      }
    }

    .button-sure {
      background-color: #0eb4c2;
      border-color: #0eb4c2;
      color: #fff;

      .el-icon-circle-plus {
        color: #fff;
      }
    }

    .button-cancel {
      background-color: #064559;
      border-color: #064559;
      color: #fff;

      .el-icon-circle-plus {
        color: #fff;
      }
    }
  }
}
.threshold-setting-main {
  .el-dropdown {
    top: 6px;
  }
}
</style>
